use chrono::{DateTime, Local};
use serde_derive::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use crate::db::pojo::pojo::{ImCollect, ImCollectStatus, ImConfig, ImConfigStatus, ImFeedback, ImFeedbackStatus, ImLabel, ImLabelStatus, ImModule, ImModuleItem, ImModuleItemStatus, ImModuleItemType, ImModuleStatus, ImSensitiveWord, ImSensitiveWordStatus, MessageType};
use crate::business::websocket::dto::json_serialize::{date_time_serde, date_time_serde_null};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigPullReq {
    #[serde(rename = "pageSize")]
    pub page_size: usize,

    #[serde(rename = "startDate", with = "date_time_serde_null")]
    pub start_date: Option<DateTime<Local>>,

    #[serde(rename = "startServerName")]
    pub start_server_name: Option<String>,

    #[serde(rename = "createDateTime", with = "date_time_serde")]
    pub create_date_time: DateTime<Local>,

    #[serde(rename = "localSeq")]
    pub local_seq: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigItemList {
    #[serde(rename = "configItems")]
    pub config_items: Vec<ConfigItem>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigItem {
    pub name: String,
    pub content: String,
    pub status: ConfigStatus,
}


#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModulePullReq {

    #[serde(rename = "pageSize")]
    pub page_size: usize,

    #[serde(rename = "startDate", with = "date_time_serde_null")]
    pub start_date: Option<DateTime<Local>>,

    #[serde(rename = "startServerName")]
    pub start_server_name: Option<String>,

    #[serde(rename = "createDateTime", with = "date_time_serde")]
    pub create_date_time: DateTime<Local>,

    #[serde(rename = "localSeq")]
    pub local_seq: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModuleInfoItemList {

    #[serde(rename = "moduleInfoItems")]
    pub module_info_items: Vec<ModuleInfoItem>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModuleInfoItem {
    pub name: String,
    pub description: Option<String>,
    pub no: i32,
    pub status: ModuleStatus,

    #[serde(rename = "moduleItemInfoList")]
    pub module_item_info_list: Vec<ModuleItemInfo>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModuleItemInfo {
    pub name: String,
    pub description: Option<String>,
    pub icon: Option<String>,
    pub url: Option<String>,
    pub params: Option<String>,
    pub r#type: ModuleItemType,
    pub no: i32,
    pub status: ModuleItemStatus,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LabelPullReq {

    #[serde(rename = "pageSize")]
    pub page_size: usize,

    #[serde(rename = "serverStartId")]
    pub server_start_id: Option<String>,

    #[serde(rename = "startDate", with = "date_time_serde_null")]
    pub start_date: Option<DateTime<Local>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LabelInfoItemList {

    #[serde(rename = "labelInfoItems")]
    pub label_info_items: Vec<LabelInfoItem>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LabelInfoItem {

    #[serde(rename = "serverId")]
    pub server_id: String,
    pub name: Option<String>,
    pub status: LabelStatus,
}


#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CollectPullReq {

    #[serde(rename = "pageSize")]
    pub page_size: usize,

    #[serde(rename = "serverStartId")]
    pub server_start_id: Option<String>,

    #[serde(rename = "startDate", with = "date_time_serde_null")]
    pub start_date: Option<DateTime<Local>>,

    #[serde(rename = "createDateTime", with = "date_time_serde")]
    pub create_date_time: DateTime<Local>,

    #[serde(rename = "localSeq")]
    pub local_seq: String,
}


#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CollectItemList {

    #[serde(rename = "collectInfoItems")]
    pub collect_info_items: Vec<CollectInfoItem>,
}


#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CollectInfoItem {

    #[serde(rename = "serverId")]
    pub server_id: String,

    #[serde(rename = "messageId")]
    pub message_id: String,

    #[serde(rename = "sessionId")]
    pub session_id: String,

    #[serde(rename = "messageType")]
    pub message_type: MessageType,
    pub content: String,

    #[serde(rename = "labelIds")]
    pub label_ids: Option<String>,
    pub status: CollectStatus,
}


#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FeedbackPullReq {
    #[serde(rename = "pageSize")]
    pub page_size: usize,

    #[serde(rename = "serverStartId")]
    pub server_start_id: Option<String>,

    #[serde(rename = "startDate", with = "date_time_serde_null")]
    pub start_date: Option<DateTime<Local>>,

    #[serde(rename = "createDateTime", with = "date_time_serde")]
    pub create_date_time: DateTime<Local>,

    #[serde(rename = "localSeq")]
    pub local_seq: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FeedbackItemList {

    #[serde(rename = "feedbackItemList")]
    pub feedback_item_list: Vec<FeedbackItem>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FeedbackItem {

    #[serde(rename = "serverId")]
    pub server_id: String,
    pub title: String,
    pub content: String,
    pub result: Option<String>,
    pub status: FeedbackStatus,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SensitiveWordPullReq {
    #[serde(rename = "pageSize")]
    pub page_size: usize,

    #[serde(rename = "serverStartId")]
    pub server_start_id: Option<String>,

    #[serde(rename = "startDate", with = "date_time_serde_null")]
    pub start_date: Option<DateTime<Local>>,

    #[serde(rename = "createDateTime", with = "date_time_serde")]
    pub create_date_time: DateTime<Local>,

    #[serde(rename = "localSeq")]
    pub local_seq: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SensitiveWordItemList {

    #[serde(rename = "sensitiveWordList")]
    pub sensitive_word_list: Vec<SensitiveWordItem>,
}


#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SensitiveWordItem {

    pub word: String,
    pub server_id: Option<String>,
    pub status: SensitiveWordStatus,
}




#[derive(Debug, Clone, Serialize_repr, Deserialize_repr, PartialEq)]
#[repr(u8)]
pub enum ConfigStatus {
    Enable = 1,
    Disable = 2,
}

#[derive(Debug, Clone, Serialize_repr, Deserialize_repr, PartialEq)]
#[repr(u8)]
pub enum ModuleStatus {
    Enable = 1,
    Disable = 2,
}


#[derive(Debug, Clone, Serialize_repr, Deserialize_repr, PartialEq)]
#[repr(u8)]
pub enum ModuleItemType {
    Page = 1,
    Origin = 2,
}


#[derive(Debug, Clone, Serialize_repr, Deserialize_repr, PartialEq)]
#[repr(u8)]
pub enum ModuleItemStatus {
    Enable = 1,
    Disable = 2,
}

#[derive(Debug, Clone, Serialize_repr, Deserialize_repr, PartialEq)]
#[repr(u8)]
pub enum LabelStatus {
    Enable = 1,
    Disable = 2,
}

#[derive(Debug, Clone, Serialize_repr, Deserialize_repr, PartialEq)]
#[repr(u8)]
pub enum CollectStatus {
    Enable = 1,
    Disable = 2,
}

#[derive(Debug, Clone, Serialize_repr, Deserialize_repr, PartialEq)]
#[repr(u8)]
pub enum FeedbackStatus {
    Enable = 1,
    Delete = 2,
    Processed = 3,
}

#[derive(Debug, Clone, Serialize_repr, Deserialize_repr, PartialEq)]
#[repr(u8)]
pub enum SensitiveWordStatus {
    Enable = 1,
    Disable = 2,
}


impl Into<ImConfig> for ConfigItem {
    fn into(self) -> ImConfig {
        ImConfig {
            id: None,
            name: self.name,
            current_user_id: "test00100".to_string(),
            content: self.content,
            status: self.status.into(),
            create_time: Local::now(),
            update_time: Local::now(),
        }
    }
}

impl Into<ImModule> for ModuleInfoItem {
    fn into(self) -> ImModule {
        ImModule {
            id: None,
            name: self.name,
            description: self.description,
            no: 0,
            status: self.status.into(),
            create_time: Local::now(),
            update_time: Local::now(),
            module_items: self.module_item_info_list.into_iter().map(|item| item.into()).collect::<Vec<ImModuleItem>>().into(),
        }
    }
}

impl Into<ImModuleStatus> for ModuleStatus {
    fn into(self) -> ImModuleStatus {
        match self {
            ModuleStatus::Enable => {ImModuleStatus::Enable},
            ModuleStatus::Disable => {ImModuleStatus::Disable }
        }
    }
}

impl Into<ImModuleItem> for ModuleItemInfo {
    fn into(self) -> ImModuleItem {
        ImModuleItem {
            id: None,
            module_id: None,
            name: self.name,
            description: self.description,
            icon: self.icon,
            url: self.url,
            params: self.params,
            no: self.no,
            status: self.status.into(),
            r#type: self.r#type.into(),
            create_time: Local::now(),
            update_time: Local::now(),
        }
    }
}


impl Into<ImConfigStatus> for ConfigStatus {
    fn into(self) -> ImConfigStatus {
        match self {
            ConfigStatus::Enable => { ImConfigStatus::Enable}
            ConfigStatus::Disable => {ImConfigStatus::Disable}
        }
    }
}

impl Into<ImModuleItemStatus> for ModuleItemStatus {
    fn into(self) -> ImModuleItemStatus {
        match self {
            ModuleItemStatus::Enable => {ImModuleItemStatus::Enable},
            ModuleItemStatus::Disable => {ImModuleItemStatus::Disable }
        }
    }
}

impl Into<ImModuleItemType> for ModuleItemType {
    fn into(self) -> ImModuleItemType {
        match self {
            ModuleItemType::Page => { ImModuleItemType::Page}
            ModuleItemType::Origin => {ImModuleItemType::Origin}
        }
    }
}

impl Into<ImLabel> for LabelInfoItem {
    fn into(self) -> ImLabel {
        ImLabel {
            id: None,
            current_user_id: "".to_string(),
            server_id: Some(self.server_id),
            name: self.name.unwrap(),
            status: self.status.into(),
            create_time: Local::now(),
            update_time: Local::now(),
        }
    }
}

impl Into<ImLabelStatus> for LabelStatus {
    fn into(self) -> ImLabelStatus {
        match self {
            LabelStatus::Enable => { ImLabelStatus::Enable}
            LabelStatus::Disable => { ImLabelStatus::Disable }
        }
    }
}

impl Into<ImCollect> for CollectInfoItem {
    fn into(self) -> ImCollect {
        ImCollect {
            id: None,
            user_id: "".to_ascii_lowercase(),
            server_id: Some(self.server_id),
            message_id: self.message_id,
            session_id: self.session_id,
            content: self.content,
            label_ids: self.label_ids,
            message_type: self.message_type,
            status: self.status.into(),
            create_time: Local::now(),
            update_time: Local::now(),
        }
    }
}

impl Into<ImCollectStatus> for CollectStatus {
    fn into(self) -> ImCollectStatus {
        match self {
            CollectStatus::Enable => { ImCollectStatus::Enable}
            CollectStatus::Disable => { ImCollectStatus::Disable }
        }
    }
}


impl Into<ImFeedback> for FeedbackItem {
    fn into(self) -> ImFeedback {
        ImFeedback {
            id: None,
            user_id: "".to_string(),
            server_id: Some(self.server_id),
            title: self.title,
            content: self.content,
            result: self.result,
            status: self.status.into(),
            create_time: Local::now(),
            update_time: Local::now(),
        }
    }
}


impl Into<ImFeedbackStatus> for FeedbackStatus {
    fn into(self) -> ImFeedbackStatus {
        match self {
            FeedbackStatus::Enable => {ImFeedbackStatus::Enable}
            FeedbackStatus::Delete => {ImFeedbackStatus::Delete}
            FeedbackStatus::Processed => {ImFeedbackStatus::Delete}
        }
    }
}


impl Into<ImSensitiveWord> for SensitiveWordItem {
    fn into(self) -> ImSensitiveWord {
        ImSensitiveWord {
            id: None,
            word: self.word,
            status: self.status.into(),
            create_time: Local::now(),
            update_time: Local::now(),
        }
    }
}

impl Into<ImSensitiveWordStatus> for SensitiveWordStatus {
    fn into(self) -> ImSensitiveWordStatus {
        match self {
            SensitiveWordStatus::Enable => {ImSensitiveWordStatus::Enable}
            SensitiveWordStatus::Disable => {ImSensitiveWordStatus::Disable}
        }
    }
}
